<?php

class App extends Singleton {

	/**
	 *
	 * @var Config
	 */
	private static $_config;
	/**
	 *
	 * @var Db
	 */
	private static $_connection;
	/**
	 *
	 * @var bool
	 */
	public static $XMLHttpRequest = false;

	protected function __construct() {
		parent::__construct();
	}

	public function init() {
		$this->db();
		if (Request::isset_('logout') || isset($_REQUEST['logout'])) UserAccess::logout();

		self::$XMLHttpRequest = isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
	}

	/**
	 *
	 * @param string $config_file
	 * @return Config
	 */
	public static function config($config_file = null) {
		if ($config_file) self::$_config = new Config($config_file);

		return self::$_config;
	}

	/**
	 * @return App
	 */
	public static function getInstance($className = __CLASS__) {
		if (isset(self::$_instances['Admin'])) return self::$_instances['Admin'];
		return parent::getInstance($className);
	}

	/**
	 * @return Doctrine_Manager
	 */
	public static final function db() {
		if (!self::$_connection) {

			//$cacheDriver = new Doctrine_Cache_Apc();

			/*$cacheConn = Doctrine_Manager::connection(new PDO('sqlite::memory:'));
			  $cacheDriver = new Doctrine_Cache_Db(array('connection' => $cacheConn, 'tableName' => 'cache'));
			  $cacheDriver->createTable();


			$manager = Doctrine_Manager::getInstance();

			$manager->setAttribute(Doctrine_Core::ATTR_QUERY_CACHE, $cacheDriver);
			$manager->setAttribute(Doctrine_Core::ATTR_QUERY_CACHE_LIFESPAN, 600);

			$manager->setAttribute(Doctrine_Core::ATTR_RESULT_CACHE, $cacheDriver);
			$manager->setAttribute(Doctrine_Core::ATTR_RESULT_CACHE_LIFESPAN, 600);*/

			$driver_options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES ' . App::config()->data('db', 'charset'));
			$dbh = new PDO(App::config()->data('db', 'dsn'), App::config()->data('db', 'user'), App::config()->data('db', 'password'), $driver_options);
			self::$_connection = Doctrine_Manager::connection($dbh);

			Doctrine_Core::loadModels(RP . '/inc/Models/');
			self::$_connection->setAttribute(Doctrine_Core::ATTR_MODEL_LOADING, Doctrine_Core::MODEL_LOADING_CONSERVATIVE);

			self::$_connection->setAttribute(Doctrine_Core::ATTR_VALIDATE, Doctrine_Core::VALIDATE_ALL);
			self::$_connection->setAttribute(Doctrine_Core::ATTR_AUTO_ACCESSOR_OVERRIDE, true);
			self::$_connection->setAttribute(Doctrine_Core::ATTR_AUTOLOAD_TABLE_CLASSES, true);
		}

		return self::$_connection;
	}

	public function run() {
		$this->init();

		$link = Request::getLink();

		$this->page = Pages::getPage($link);

		if (!$this->page) Request::redirect(404);

		$this->render();
	}

	public function render() {
		$this->renderBlocks();
		$this->tpl()->assign('page', $this->page);
		$this->tpl()->display('index.html');
	}

	public function renderBlocks() {
		$blocks = $this->page->Blocks;
		$fields = array();

		$maxField = $this->page->maxField;

		for ($i = 0; $i <= ($maxField > 15 ? $maxField : 15); $i++) {
			$fields['field_' . $i] = "";
		}

		if (App::getInstance()->config()->data('smarty_debug')) {
			foreach ($fields as $i => $field) {
				$fields[$i] = "<div id=\"$i\" class=\"debug_field\">" . $field;
			}
		}

		foreach ($blocks as $block) {
			$module = "Modules_" . ucwords($block->Module->name);
			$action = ($block->field == 0 && !empty($_REQUEST['action'])) ? $_REQUEST['action'] : $block->action;
			$module = new $module($action);
			$module->block = $block;

			$fields['field_' . $block->field] .= $module->render();
		}
		
		if (App::getInstance()->config()->data('smarty_debug')) {
			foreach ($fields as $i => $field) {
				$fields[$i] = $field . "</div>";
			}
		}

		$this->tpl()->assign($fields);
	}

	protected $_tpl;

	/**
	 * @return Templater
	 */
	public function tpl() {
		if (!$this->_tpl) {
			$this->_tpl = new Templater(RP . "tpl/" . $this->page->Template->name . "/");
			$this->_tpl->caching = false;
		}

		return $this->_tpl;
	}

	public static function redirect($url) {
		trigger_error("App::redirect() is depricated", E_USER_NOTICE);
		return Request::redirect($url);
	}

	private static $_coreScriptsNames = array(
		'jquery' => '/js/jquery-1.5.1.js',
		'base' => '/js/base_edit.js',
		'colorbox' => '/js/colorbox/jquery.colorbox-min.js',
		'tiny_mce' => '/js/tiny_mce/tiny_mce.js',
		'jstree' => '/js/jstree/jquery.jstree.js',
		'jquery-ui' => '/js/jquery-ui/jquery-ui-1.8.10.min.js',
	);
	private static $_coreStylesNames = array(
		'colorbox' => '/js/colorbox/theme_1/colorbox.css',
		'jquery-ui' => '/js/jquery-ui/css/redmond/jquery-ui-1.8.10.custom.css',
	);

	public static function registerCoreStyle($name) {
		$_styles = App::getInstance()->tpl()->getTemplateVars("_styles");
		if (!$_styles) $_styles = array();
		if (!isset($_styles[$name])) $_styles[$name] = self::$_coreStylesNames[$name];
		App::getInstance()->tpl()->assign('_styles', $_styles);
	}

	public static function registerStyle($src) {
		$_styles = App::getInstance()->tpl()->getTemplateVars("_styles");
		if (!$_styles) $_styles = array();
		if (!isset($_styles[$src])) $_styles[$src] = $src;
		App::getInstance()->tpl()->assign('_styles', $_styles);
	}

	public static function registerCoreScript($name) {
		$_scripts = App::getInstance()->tpl()->getTemplateVars("_scripts");
		if (!$_scripts) $_scripts = array();
		if (!isset($_scripts[$name])) $_scripts[$name] = self::$_coreScriptsNames[$name];
		App::getInstance()->tpl()->assign('_scripts', $_scripts);
	}

	public static function registerScript($src) {
		$_scripts = App::getInstance()->tpl()->getTemplateVars("_scripts");
		if (!$_scripts) $_scripts = array();
		if (!isset($_scripts[$src])) $_scripts[$src] = $src;
		App::getInstance()->tpl()->assign('_scripts', $_scripts);
	}

	public static function accessDenied($module, $action, $type) {
		header('HTTP/1.1 403 Forbidden');
		$str = App::getInstance()->tpl()->assign(array(
					"module" => $module,
					"action" => $action,
					"type" => $type
				));
		//$this->tpl()->assign('field_0', $this->tpl()->fetch('error.html');
	}

}